]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
shell-app: Add discrete GPU support for NVidia drivers
authorBastien Nocera <hadess@hadess.net>
Thu, 24 Oct 2019 12:39:25 +0000 (14:39 +0200)
committerBastien Nocera <hadess@hadess.net>
Thu, 12 Dec 2019 23:44:28 +0000 (00:44 +0100)
Use data from switcheroo-control to know which environment variables
to use to launch an application on the discrete GPU. switcheroo-control
version 2.0 or newer should be installed on Linux platforms.

Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1810
src/shell-app.c

index c237a225eb2861a2332cc3b0fa0d42b4f277c916..5704f75b1c512537164ea6b33cb0e195495c1553 100644 (file)
@@ -19,6 +19,7 @@
 #include "st.h"
 #include "gtkactionmuxer.h"
 #include "org-gtk-application.h"
+#include "switcheroo-control.h"
 
 #ifdef HAVE_SYSTEMD
 #include <systemd/sd-journal.h>
@@ -1255,6 +1256,60 @@ wait_pid (GDesktopAppInfo *appinfo,
   g_child_watch_add (pid, (GChildWatchFunc) g_spawn_close_pid, NULL);
 }
 
+static void
+apply_discrete_gpu_env (GAppLaunchContext *context,
+                        ShellGlobal       *global)
+{
+  GDBusProxy *proxy;
+  GVariant* variant;
+  guint num_children, i;
+
+  proxy = _shell_global_get_switcheroo_control (global);
+  if (!proxy)
+    {
+      g_warning ("Could not apply discrete GPU environment, switcheroo-control not available");
+      return;
+    }
+
+  variant = shell_net_hadess_switcheroo_control_get_gpus (SHELL_NET_HADESS_SWITCHEROO_CONTROL (proxy));
+  if (!variant)
+    {
+      g_warning ("Could not apply discrete GPU environment, no GPUs in list");
+      return;
+    }
+
+  num_children = g_variant_n_children (variant);
+  for (i = 0; i < num_children; i++)
+    {
+      g_autoptr(GVariant) gpu;
+      g_autoptr(GVariant) env = NULL;
+      g_autoptr(GVariant) default_variant = NULL;
+      g_autofree const char **env_s = NULL;
+      guint j;
+
+      gpu = g_variant_get_child_value (variant, i);
+      if (!gpu ||
+          !g_variant_is_of_type (gpu, G_VARIANT_TYPE ("a{s*}")))
+        continue;
+
+      /* Skip over the default GPU */
+      default_variant = g_variant_lookup_value (gpu, "Default", NULL);
+      if (!default_variant || g_variant_get_boolean (default_variant))
+        continue;
+
+      env = g_variant_lookup_value (gpu, "Environment", NULL);
+      if (!env)
+        continue;
+
+      env_s = g_variant_get_strv (env, NULL);
+      for (j = 0; env_s[j] != NULL; j = j + 2)
+        g_app_launch_context_setenv (context, env_s[j], env_s[j+1]);
+      return;
+    }
+
+  g_warning ("Could not find discrete GPU data in switcheroo-control");
+}
+
 /**
  * shell_app_launch:
  * @timestamp: Event timestamp, or 0 for current event timestamp
@@ -1290,7 +1345,7 @@ shell_app_launch (ShellApp     *app,
   global = shell_global_get ();
   context = shell_global_create_app_launch_context (global, timestamp, workspace);
   if (discrete_gpu)
-    g_app_launch_context_setenv (context, "DRI_PRIME", "1");
+    apply_discrete_gpu_env (context, global);
 
   /* Set LEAVE_DESCRIPTORS_OPEN in order to use an optimized gspawn
    * codepath. The shell's open file descriptors should be marked CLOEXEC